#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <linux/joystick.h>  // 添加此头文件

#define PS2_DEVICE "/dev/input/js0"
#define AXIS_THRESHOLD 25000  // 摇杆灵敏度阈值

int main() {
    struct js_event js;
    int fd;
    // 存储摇杆和方向键状态，避免重复输出
    short left_stick_x = 0, left_stick_y = 0;
    short right_stick_x = 0, right_stick_y = 0;
    short dpad_x = 0, dpad_y = 0;  // 新增：方向键状态

    // 打开手柄设备文件
    fd = open(PS2_DEVICE, O_RDONLY);
    if (fd < 0) {
        perror("打开手柄设备失败");
        return 1;
    }

    printf("PS2手柄已连接，开始监听按键事件...\n");
    printf("按Ctrl+C退出程序\n");

    // 非阻塞模式读取
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    while (1) {
        // 读取手柄事件
        if (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
            // 处理按键事件
            if (js.type & JS_EVENT_BUTTON) {
                if (js.value) {  // 按键按下
                    switch (js.number) {
                        case 0:
                            printf("信号1: 按键△按下\n");
                            break;
                        case 1:
                            printf("信号2: 按键O按下\n");
                            break;
                        case 2:
                            printf("信号3: 按键X按下\n");
                            break;
                        case 3:
                            printf("信号4: 按键□按下\n");
                            break;
                        case 4:
                            printf("信号5: L1按下\n");
                            break;
                        case 5:
                            printf("信号6: R1按下\n");
                            break;
                        case 6:
                            printf("信号7: L2按下\n");
                            break;
                        case 7:
                            printf("信号8: R2按下\n");
                            break;
                        case 8:
                            printf("信号9: SELECT按下\n");
                            break;
                        case 9:
                            printf("信号10: START按下\n");
                            break;
                        case 10:
                            printf("信号11: 左摇杆按下\n");
                            break;
                        case 11:
                            printf("信号12: 右摇杆按下\n");
                            break;
                        // case 12:  // MODE按键
                        //     printf("信号13: MODE按下\n");
                        //     break;
                        // 如果方向键被映射为按键，这里会触发
                        // case 13:  // 方向键上
                        //     printf("信号14: 方向键上按下\n");
                        //     break;
                        // case 14:  // 方向键右
                        //     printf("信号15: 方向键右按下\n");
                        //     break;
                        // case 15:  // 方向键下
                        //     printf("信号16: 方向键下按下\n");
                        //     break;
                        // case 16:  // 方向键左
                        //     printf("信号17: 方向键左按下\n");
                        //     break;
                        default:
                            printf("未知按键: %d\n", js.number);
                    }
                }
            }
            // 处理摇杆和方向键轴事件
            else if (js.type & JS_EVENT_AXIS) {
                switch (js.number) {
                    case 0:  // 左摇杆X轴
                        left_stick_x = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号18: 左摇杆右\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号19: 左摇杆左\n");
                        }
                        break;
                    case 1:  // 左摇杆Y轴
                        left_stick_y = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号20: 左摇杆下\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号21: 左摇杆上\n");
                        }
                        break;
                    case 2:  // 右摇杆X轴
                        right_stick_x = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号22: 右摇杆右\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号23: 右摇杆左\n");
                        }
                        break;
                    case 3:  // 右摇杆Y轴
                        right_stick_y = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号24: 右摇杆下\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号25: 右摇杆上\n");
                        }
                        break;
                    // 新增：检测方向键是否被映射为轴
                    case 4:  // 方向键X轴（左右）
                        dpad_x = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号15: 方向键右\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号17: 方向键左\n");
                        }
                        break;
                    case 5:  // 方向键Y轴（上下）
                        dpad_y = js.value;
                        if (js.value > AXIS_THRESHOLD) {
                            printf("信号16: 方向键下\n");
                        } else if (js.value < -AXIS_THRESHOLD) {
                            printf("信号14: 方向键上\n");
                        }
                        break;
                }
            }
        }

        // 短暂休眠避免CPU占用过高
        usleep(10000);
    }

    close(fd);
    return 0;
}
